<template>
  <el-container :style="{ height: containerHeight + `px` }">
    <!-- 左侧部门菜单树 -->
    <el-aside style="
        padding: 10px 0px 0px 0px;
        background: #fff;
        border-right: 1px solid #dfe6ec;
      " width="230px">
      <el-tree style="font-size: 14px" ref="leftTree" :data="deptList" node-key="id" :props="defaultProps"
        default-expand-all empty-text="暂无数据" :show-checkbox="false" :highlight-current="true"
        :expand-on-click-node="false" @node-click="handleNodeClick">
        <div class="custom-tree-node" slot-scope="{ node, data }">
          <div>
            <span v-if="data.children.length == 0">
              <i class="el-icon-document"></i>
            </span>
            <span v-else @click.stop="changeIcon(data)">
              <svg-icon v-if="data.open" icon-class="add-s" />
              <svg-icon v-else icon-class="sub-s" />
            </span>
            <!-- 名称 -->
            <span style="margin-left: 3px">{{ node.label }}</span>
          </div>
        </div>
      </el-tree></el-aside>
    <!-- 右侧数据列表 -->
    <el-main><!-- 查询条件 -->
      <el-form :model="searchModel" ref="searchForm" label-width="80px" :inline="true" size="small">
        <el-form-item>
          <el-input v-model="searchModel.username" placeholder="请输入用户名" />
        </el-form-item>
        <el-form-item>
          <el-input v-model="searchModel.realName" placeholder="请输入真实姓名" />
        </el-form-item>
        <el-form-item>
          <el-input v-model="searchModel.phone" placeholder="请输入电话" />
        </el-form-item>
        <el-form-item>
          <el-button icon="el-icon-search" plain type="primary"
            @click="search(departmentId, pageNo, pageSize)">查询</el-button>
          <el-button icon="el-icon-delete" type="info" plain @click="resetValue()">重置</el-button>
          <el-button v-if="hasPermission('sys:department:add')" plain icon="el-icon-plus" size="small" type="success"
            @click="openAddWindow()">新增</el-button>
        </el-form-item>
      </el-form>
      <!-- 数据表格 -->
      <el-table :data="userList" :height="tableHeight" border stripe style="width: 100%; margin-bottom: 10px">
        <el-table-column prop="username" label="用户名" align="center"></el-table-column>
        <el-table-column prop="realName" align="center" label="姓名"></el-table-column>
        <el-table-column prop="departmentName" align="center" label="所属部门"></el-table-column>
        <el-table-column prop="phone" align="center" label="电话"></el-table-column>
        <el-table-column prop="email" align="center" label="邮箱"></el-table-column>
        <el-table-column label="操作" align="center" width="290">
          <template slot-scope="scope">

            <el-button icon="el-icon-edit" type="primary" size="small" @click="handleEdit(scope.row)">
              编辑
            </el-button>
            <!-- <span @click="handleDelete(scope.row)" style="color: #1890FF;cursor: pointer;">
              删除
            </span> -->
            <el-button icon="el-icon-delete" type="danger" size="small" @click="handleDelete(scope.row)">删除
            </el-button>
            <!-- <span @click="assignRole(scope.row)" style="color: #1890FF;cursor: pointer;">
              分配角色
            </span> -->
            <el-button icon="el-icon-setting" type="primary" size="small" @click="assignRole(scope.row)">分配角色
            </el-button>
          </template></el-table-column></el-table>

      <!-- 分页工具栏 -->
      <el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange"
        :current-page="pageNo" :page-sizes="[10, 20, 30, 40, 50]" :page-size="10"
        layout="total, sizes, prev, pager, next, jumper" :total="total">
      </el-pagination>

      <!-- 添加和编辑用户窗口 -->
      <system-dialog :title="userDialog.title" :height="userDialog.height" :width="userDialog.width"
        :visible="userDialog.visible" @onClose="onClose" @onConfirm="onConfirm">
        <div slot="content">
          <el-form :model="user" ref="userForm" :rules="rules" label-width="80px" :inline="true" size="small">
            <el-form-item prop="username" label="用户名">
              <el-input v-model="user.username"></el-input>
            </el-form-item>
            <el-form-item prop="password" v-if="user.id === ''" label="密码">
              <el-input type="password" v-model="user.password"></el-input>
            </el-form-item>
            <el-form-item prop="departmentName" label="所属部门">
              <el-input v-model="user.departmentName" :readonly="true" @click.native="selectDepartment()"></el-input>
            </el-form-item>
            <el-form-item prop="realName" label="姓名">
              <el-input v-model="user.realName"></el-input>
            </el-form-item>
            <el-form-item prop="phone" label="电话">
              <el-input v-model="user.phone"></el-input>
            </el-form-item>
            <el-form-item label="昵称">
              <el-input v-model="user.nickName"></el-input>
            </el-form-item>
            <el-form-item label="邮箱">
              <el-input v-model="user.email"></el-input>
            </el-form-item>
            <el-form-item prop="gender" label="性别">
              <el-radio-group v-model="user.gender">
                <el-radio :label="0">男</el-radio>
                <el-radio :label="1">女</el-radio>
              </el-radio-group>
            </el-form-item>
            <br />
            <!-- 用户头像 -->
            <el-form-item label="头像">
              <el-upload :show-file-list="false" :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload"
                class="avatar-uploader" :data="uploadHeader"
                action="http://localhost:8888/api/oss/file/upload?module=avatar">
                <img v-if="user.avatar" :src="user.avatar" />
                <i v-else class="el-icon-plus avatar-uploader-icon" />
              </el-upload>
            </el-form-item>
            <!-- 用户头像：待补充 -->
          </el-form>
        </div>
      </system-dialog>
    </el-main>

    <!-- 所属部门弹框 -->
    <system-dialog :title="parentDialog.title" :width="parentDialog.width" :height="parentDialog.height"
      :visible="parentDialog.visible" @onClose="onParentClose" @onConfirm="onParentConfirm">
      <div slot="content">
        <el-tree ref="parentTree" :data="parentList" default-expand-all node-key="id" :props="parentProps"
          :show-checkbox="false" :highlight-current="true" :expand-on-click-node="false" @node-click="parentClick">
          <div class="customer-tree-node" slot-scope="{ node, data }">
            <span v-if="data.children.length == 0">
              <i class="el-icon-document" />
            </span>
            <span v-else @click.stop="openParentBtn(data)">
              <svg-icon v-if="data.open" icon-class="add-s" />
              <svg-icon v-else icon-class="sub-s" />
            </span>
            <span style="margin-left: 3px">{{ node.label }}</span>
          </div>
        </el-tree>
      </div>
    </system-dialog>

    <!-- 分配角色窗口 -->
    <system-dialog :title="assignDialog.title" :height="assignDialog.height" :width="assignDialog.width"
      :visible="assignDialog.visible" @onClose="onAssignClose" @onConfirm="onAssignConfirm">
      <div slot="content">
        <!-- 分配角色数据列表 -->
        <el-table ref="assignRoleTable" v-loading="loading" :data="assignRoleList" border stripe :height="assignHeight"
          style="width: 100%; margin-bottom: 10px" @selection-change="handleSelectionChange">
          <el-table-column type="selection" width="55" align="center"></el-table-column>
          <el-table-column prop="roleCode" label="角色编码" />
          <el-table-column prop="roleName" label="角色名称" />
          <el-table-column prop="remark" label="角色备注" />
        </el-table>
        <!-- 分页工具栏 -->
        <el-pagination @size-change="assignSizeChange" @current-change="assignCurrentChange"
          :current-page.sync="roleVo.pageNo" :page-sizes="[10, 20, 30, 40, 50]" :page-size="roleVo.pageSize"
          layout="total, sizes, prev, pager, next, jumper" :total="roleVo.total" background>
        </el-pagination>
      </div>
    </system-dialog>
  </el-container>
</template>

<script>
  import {
    getUserListApi,
    addUserApi,
    editUserApi,
    deleteUserApi,
    getAssignRoleListApi,
    getRoleIdByUserIdApi,
    assignRoleSaveApi,
  } from "@/api/user";
  import { getDepartmentListApi } from "@/api/department";
  import SystemDialog from "@/components/system/SystemDialog.vue";
  import { getToken } from "@/utils/auth";
  // import
  export default {
    name: "userList",

    components: {
      SystemDialog,
    },

    data() {
      //自定义验证规则
      let validatePhone = (rule, value, callback) => {
        if (!value) {
          callback(new Error("请输入手机号码"));
          //使用正则表达式进行验证手机号码
        } else if (!/^1[3456789]\d{9}$/.test(value)) {
          callback(new Error("手机号格式不正确"));
        } else {
          callback();
        }
      };
      return {
        loading: false,
        //分配角色窗口属性
        assignDialog: {
          title: "",
          visible: false,
          width: 800,
          height: 410,
        },
        //角色对象
        roleVo: {
          pageNo: 1,
          pageSize: 10,
          userId: "",
          total: 0,
        },
        assignRoleList: [], //角色列表
        assignHeight: 0, //分配角色表格高度
        selectedIds: [], //被选中的角色id
        selectedUserId: "", //被分配角色的用户ID
        uploadHeader: {
          token: getToken(),
        },
        //选择所属部门窗口属性
        parentDialog: {
          title: "选择所属部门",
          width: 300,
          height: 450,
          visible: false,
        },
        //树节点属性
        parentProps: {
          children: "children",
          label: "departmentName",
        },
        parentList: [], //所属部门节点数据
        //树节
        //用户对象
        user: {
          id: "",
          departmentId: "",
          departmentName: "",
          email: "",
          realName: "",
          phone: "",
          nickName: "",
          password: "",

          username: "",
          gender: "",
          avatar: "",
        },
        userDialog: {
          title: "",
          height: 510,
          width: 610,
          visible: false,
        },
        rules: {
          departmentName: [
            { required: true, trigger: "change", message: "请选择所属部门" },
          ],
          realName: [{ required: true, trigger: "blur", message: "请填写姓名" }],
          phone: [{ trigger: "blur", validator: validatePhone }],
          username: [
            { required: true, trigger: "blur", message: "请填写登录名" },
          ],
          password: [
            { required: true, trigger: "blur", message: "请填写登录密码" },
          ],
          gender: [{ required: true, trigger: "change", message: "请选择性别" }],
        },
        userList: [], // 用户列表
        tableHeight: 0,

        // 查询对象
        searchModel: {
          username: "",
          realName: "",
          phone: "",
          pageNo: 1,
          departmentId: "",
          pageSize: 10,
        },
        containerHeight: 0,
        deptList: [], // 部门数组
        // 树节点属性
        defaultProps: {
          children: "children",
          label: "departmentName",
        },
        pageNo: 1, // 当前页码
        pageSize: 10, // 每页显示数量
        total: 0,
        departmentId: "",
      };
    },

    created() {
      this.getDepartmentList();
      this.search(this.departmentId);
    },

    mounted() {
      this.$nextTick(() => {
        //内容高度
        this.containerHeight = window.innerHeight - 20;
        //表格高度
        this.tableHeight = window.innerHeight - 220;
        //   this.tableHeight = 300;
        //角色表格高度
        this.assignHeight = window.innerHeight - 350;
      });
    },

    methods: {
      /**
       * 页码改变
       */
      assignCurrentChange(page) {
        this.roleVo.pageNo = page;
        this.getAssignRoleList(page, this.roleVo.pageSize);
      },
      /**
       *  数量改变
       */
      assignSizeChange(size) {
        this.roleVo.pageSize = size;
        this.getAssignRoleList(this.roleVo.page, size);
      },
      /**
       * 复选框选中事件 角色id
       */
      handleSelectionChange(row) {
        console.log(row);
        // 保存复选框选中的，转化id
        this.selectedIds = row.map((item) => item.id);
      },
      onAssignClose() {
        //隐藏窗口
        this.assignDialog.visible = false;
      },
      /**
       * 分配角色确认事件
       */
      async onAssignConfirm() {
        //隐藏窗口
        this.assignDialog.visible = false;
        if (this.selectedIds.length == 0) {
          this.$message.warning("请选择要分配的角色");
          return;
        }
        let params = {
          userId: this.selectedUserId,
          roleIds: this.selectedIds,
        };
        let res = await assignRoleSaveApi(params);
        if (res.success) {
          this.$message.success("分配角色成功");
          this.userDialog.visible = false;
          this.search(this.departmentId);
        } else {
          this.$message.error("分配角色失败");
        }
      },
      /**
       * 分配角色按钮
       */
      async assignRole(row) {
        // 清除选择角色列表
        this.selectedIds = [];
        this.selectedUserId = row.id;
        this.assignDialog.title = "分配角色";
        this.assignDialog.visible = true;
        //   调用

        // 查询当前登录用户所拥有的的角色信息
        this.getAssignRoleList();
        let params = {
          id: row.id,
        };
        //  根据用户id 查询用户角色列表
        let res = await getRoleIdByUserIdApi(params);
        if (res.success && res.data) {
          this.selectedIds = res.data;
          this.selectedIds.forEach((key) => {
            this.assignRoleList.forEach((item) => {
              if (key == item.id) {
                this.$refs.assignRoleTable.toggleRowSelection(item, true);
              }
            });
          });
        }
      },
      /**
       *  查出当前登录用户所拥有的角色信息
       */
      async getAssignRoleList(pageNo = 1, pageSize = 10) {
        this.roleVo.pageNo = pageNo;
        this.roleVo.pageSize = pageSize;
        //  请求
        let res = await getAssignRoleListApi(this.roleVo);
        if (res.success) {
          this.assignRoleList = res.data.records;
          this.roleVo.total = res.data.total;
        }
      },
      async handleDelete(row) {
        let confirm = await this.$myconfirm("是否要删除用户？");
        if (confirm) {
          let res = await deleteUserApi({ id: row.id });
          if (res.success) {
            this.$message.success(res.message);
            this.search(this.departmentId);
          } else {
            this.$message.error(res.message);
          }
        }
      },
      handleEdit(row) {
        // 数据回显
        this.$objCopy(row, this.user);
        this.userDialog.visible = true;
        this.userDialog.title = "编辑用户信息";
      },
      /**
       * 上传成功回调
       * @param res
       * @param file
       */
      handleAvatarSuccess(res, file) {
        this.user.avatar = res.data;
        // 强制重新渲染
        this.$forceUpdate();
      },
      /**
       * 上传校验
       * @param file
       * @returns {boolean}
       */
      beforeAvatarUpload(file) {
        const isJPG = file.type === "image/jpeg";
        const isLt2M = file.size / 1024 / 1024 < 2;
        if (!isJPG) {
          this.$message.error("上传头像图片只能是 JPG 格式!");
        }
        if (!isLt2M) {
          this.$message.error("上传头像图片大小不能超过 2MB!");
        }
        return isJPG && isLt2M;
      },
      /**
       * 打开选择上级部门窗口
       */
      async selectDepartment() {
        //查询上级部门数据
        let res = await getDepartmentListApi(null);
        //判断是否成功
        if (res.success) {
          this.parentList = res.data;
        }
        //显示窗口
        this.parentDialog.visible = true;
      },
      /**
       * 选择上级部门取消事件
       */
      onParentClose() {
        this.parentDialog.visible = false; //关闭窗口
      },
      /**
       * 选择上级部门确认事件
       */
      onParentConfirm() {
        this.parentDialog.visible = false;
      },
      //上级部门树节点点击事件
      parentClick(data) {
        this.user.departmentId = data.id;
        this.user.departmentName = data.departmentName;
      },
      //上级部门树加号 减号 图标点击事件
      openParentBtn(data) {
        data.open = !data.open;
        this.$refs.parentTree.store.nodesMap[data.id].expanded = !data.open;
      },
      /**
       * 新增确认点击事件
       */
      onConfirm() {
        this.$refs.userForm.validate(async (valid) => {
          if (valid) {
            //   alert("校验通过");
            let res = null;
            if (this.user.id == "") {
              // 新增
              res = await addUserApi(this.user);
            } else {
              // 修改
              res = await editUserApi(this.user);
            }
            if (res.success) {
              this.$message.success(res.message);
              this.userDialog.visible = false;
              this.search(this.departmentId);
            } else {
              // 失败
              this.$message.error(res.message);
            }
          }
        });
      },
      /**
       * 新增或编辑取消事件
       */
      onClose() {
        this.userDialog.visible = false; //关闭窗口
      },
      openAddWindow() {
        this.$resetForm("userForm", this.user);
        this.userDialog.visible = true;
        this.userDialog.title = "新增用户";
      },
      resetValue() {
        // 查询对象
        this.searchModel = {
          username: "",
          realName: "",
          phone: "",
          pageNo: 1,
          departmentId: "",
          pageSize: 10,
        };
        this.search(this.departmentId);
      },
      /**
       *  查询用户列表
       */
      async search(departmentId, pageNo = 1, pageSize = 10) {
        this.searchModel.departmentId = departmentId;
        this.searchModel.pageNo = pageNo;
        this.searchModel.pageSize = pageSize;
        try {
          this.loading = true
          let res = await getUserListApi(this.searchModel);
          this.userList = res.data.records;
          console.log("--123123");
          console.log(this.userList);
          this.total = res.data.total;
        } catch (e) {
          console.log(e)
        } finally {
          this.loading = false

        }

      },
      handleCurrentChange(page) {
        //   this.pageNo = page;
        //   this.search(this.departmentId);
        this.search(this.departmentId, page, this.pageSize);
      },
      /**
       *
       */
      handleSizeChange(size) {
        this.search(this.departmentId, this.pageNo, size);
      },
      /**
       * 查询部门列表
       */
      async getDepartmentList() {
        let res = await getDepartmentListApi();
        console.log(res);
        if (res.success) {
          this.deptList = res.data;
          // 树加载完毕以后，点击第一个
          let departmentId = res.data[0].id; // 获取到第一个id

          // alert(departmentId);
          // const firstNode = document.querySelector(".custom-tree-node");
          // const firstNode = document.querySelector(".el-tree-node");
          // console.log();
          // firstNode.click();
          let a;
          this.handleNodeClick(a, departmentId);
        }
      },
      /**
       *  departmentId 是在获取树形部门,
       */
      handleNodeClick(data, departmentId) {
        // 将当前选择 的节点id赋值给departmentID
        if (data) {
          this.departmentId = data.id;
        } else {
          this.departmentId = departmentId;
        }
        //   this.departmentId = data.id | departmentId;
        //  查询用户信息
        this.search(this.departmentId);
      },
      //加减号图标点击事件
      changeIcon(data) {
        //修改折叠展开状态
        data.open = !data.open;
        this.$refs.leftTree.store.nodesMap[data.id].expanded = !data.open;
      },
    },
  };
</script>

<style lang="scss" scoped>
   ::v-deep .has-gutter th {
    background-color: #F2F6FC;
  }
  ::v-deep .has-gutter th {
    background-color: #F2F6FC;
  }

  .iconList {
    width: 400px;
    height: 300px;
    overflow-y: scroll;
    overflow-x: hidden;
    display: flex;
    justify-content: space-around;

    flex-wrap: wrap;

    i {
      display: inline-block;
      width: 60px;
      height: 45px;
      color: #000000;
      font-size: 20px;
      border: 1px solid #e6e6e6;
      border-radius: 4px;
      cursor: pointer;
      text-align: center;
      line-height: 45px;
      margin: 5px;

      &:hover {
        color: orange;
        border-color: orange;
      }
    }
  }

  .chooseIcons {
    width: 175px;
    background-color: #ffffff;
    background-image: none;
    border-radius: 4px;
    border: 1px solid #dcdfe6;
    box-sizing: border-box;
    color: #606266;
    display: inline-block;
    font-size: inherit;
    height: 33px;
    line-height: 25px;
    outline: none;
    padding: 0 15px;
    transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
  }

  .avatar-uploader .el-upload {
    border: 1px dashed #d9d9d9;
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
  }

  .avatar-uploader .el-upload:hover {
    border-color: #409eff;
  }

  .avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 178px;
    height: 178px;
    line-height: 178px;
    text-align: center;
  }

  .avatar {
    width: 178px;
    height: 178px;
    display: block;
  }
</style>